<template>
  <div v-if="!isSidebarCollapsed" class="tree-wrapper" ref="treeWrapper">
    <!--  :data="treeData" -->
    <!-- :data="filteredTreeData" -->
    <el-tree 
      ref="tree"     
      :data="treeData"
      :filter-node-method="filterNode"
      :props="defaultProps"
      draggable
      @node-drag-start="handleDragStart"
      @node-drag-end="handleDragEnd"
      @node-drop="handleDrop"
      @node-click="handleNodeClick"
      default-expand-all
      highlight-current
      :expand-on-click-node="false"
    >
      <template #default="{ node, data }">
        <span class="custom-tree-node" :style="{ maxWidth: sidebarWidth }">
          <!-- 创建一个新的容器来包裹图标和文本 -->
          <span class="node-content" @click="handleViewClick(data)">
            <el-icon v-if="data.nodeType === 'folder'"><Folder /></el-icon>
            <el-icon v-else><Document /></el-icon>
            <!-- <span>{{ node.label }}</span> -->
            <span class="node-label" :title="node.label" :style="{ width: labelMaxWidth(node) }">{{ node.label }}</span>
          </span>

          
          <el-popover
            placement="right"
            :title="node.label"
            width="200"
            trigger="click"
            v-if="!isSidebarCollapsed&&isAdmin&&operMenu"
          >
            <template #reference>
              <a>
                <el-icon class="vertical-more"><More /></el-icon>
              </a>
            </template>
            <el-menu class="tree-trigger-nav">
              <!-- 使用 filteredButtonsMap 来获取过滤后的按钮 -->
              <el-menu-item 
                v-for="(item, index) in filteredButtonsMap.get(node)" 
                :key="index" 
                @click="handleNavClick(item.methodName, item.operation, data, node)"
              >
                <el-icon><component :is="item.icon" /></el-icon>
                <span>{{ item.name }}</span>
              </el-menu-item>
            </el-menu>
          </el-popover>

        </span>
      </template>
    </el-tree>
  </div>
</template>

<script lang="ts">
import useUserStore from '@/store/modules/user';
import {
More
} from '@element-plus/icons-vue';
import { computed, defineComponent, markRaw, PropType, reactive, ref, toRefs, watch } from 'vue';

interface TriggerButtonItem {
  name: string;
  methodName: string;
  icon: any;
  operation: string;
}

export default defineComponent({
  props: {
    treeData: {
      type: Array as PropType<any[]>,
      required: true
    },
    operMenu: {
      type: Boolean,
      required: true
    },
    defaultProps: {
      type: Object,
      required: true
    },
    isSidebarCollapsed: {
      type: Boolean,
      required: true
    },
    triggerButton: {
      type: Array as PropType<TriggerButtonItem[]>,
      required: true
    },
    sidebarWidth: {
      type: String,
      default: '200px' // 默认值
    },
    searchQuery: {
      type: String,
      default: ''
    }
  },
  emits: ['view-click','node-click', 'drag-start', 'drag-end', 'drop', 'nav-click'],
  setup(props, { emit }) {

    const userStore = useUserStore();
    const isAdmin = computed(() => userStore.getRoleName.includes('admin'));

    // 创建对树组件的引用
    const tree = ref<InstanceType<typeof ElTree>>();

    // 监听 searchQuery 的变化并调用树的 filter 方法
    watch(() => props.searchQuery, (val) => {
      debugger;
      tree.value?.filter(val);
    });

    const filterNode = (value: string, data: Tree) => {
      if (!value) return true
      return data.label.includes(value)
    }
    
    // 
    const state = reactive({
      selectedNode: null, // 当前选中的节点
      filteredButtonsMap: new Map<any, TriggerButtonItem[]>(), // 存储每个节点的过滤按钮
    });

    const labelMaxWidth = (node: any) => {
       // 固定右侧操作按钮的宽度（包括图标和间距）
      const rightButtonWidth = 50; // 右侧操作按钮的固定宽度
      const iconWidth = 24; // 左侧图标的宽度
      const levelIndent = 16; // 每层级的缩进宽度

      // 计算层级缩进的总宽度
      const levelWidth = node.level * levelIndent;

      // 计算可用宽度
      const availableWidth = parseInt(props.sidebarWidth, 10) - levelWidth - iconWidth - rightButtonWidth;

      // 返回可用宽度
      return `${availableWidth}px`;
    };

    const handleNodeClick = (data: any, node: any) => {
      // 更新选中的节点
      state.selectedNode = node;

      // 动态更新选中节点的过滤按钮
      updateFilteredButtons(node);

      // 触发父组件的事件
      emit('node-click', data);
    };

    const handleViewClick = (data:any)=>{
      emit('view-click', data);
    }

    const handleDragStart = (draggingNode: any) => {
      emit('drag-start', draggingNode);
    };

    const handleDragEnd = (draggingNode: any, dropNode: any, dropType: string) => {
      emit('drag-end', draggingNode, dropNode, dropType);
    };

    const handleDrop = (draggingNode: any, dropNode: any, dropType: string, ev: Event) => {
      emit('drop', draggingNode, dropNode, dropType, ev);
    };

    const handleNavClick = (methodName: string, operation: string, data: any, node: any) => {
      
      // visible.value = false;
      emit('nav-click', methodName, operation, data, node);
    };

    // 根据节点层级过滤触发按钮，并确保不返回 undefined 或 null
    const updateFilteredButtons = (node: any) => {
      if (!node || !Array.isArray(props.triggerButton)) return;

      let buttons = [...props.triggerButton];
      // if (node.level > 1) {
      //   buttons = buttons.filter(button => button.methodName !== 'openDialog');
      // }
      // buttons = buttons.filter(button => button.operation === 'all' || button.operation === node.data.operation);
      if(node.data&&node.data.nodeType){
        if(node.data.nodeType==='file'){
          buttons = buttons.filter(button => button.operation != 'create');
        }else{
          buttons = buttons.filter(button => button.operation != 'import');
          if (node.level == 1) {
            buttons = buttons.filter(button => button.operation == 'create');
          }
        }
      }
      // 确保每个按钮都是一个对象并且包含所有必要的属性
      const filteredButtons = buttons.filter((button): button is TriggerButtonItem => 
        typeof button === 'object' &&
        'name' in button &&
        'methodName' in button &&
        'icon' in button &&
        'operation' in button
      );

      // 更新对应节点的过滤按钮列表
      // state.filteredButtonsMap.set(node, filteredButtons);
      // 使用 markRaw 避免将按钮列表变为响应式对象
      state.filteredButtonsMap.set(node, markRaw(filteredButtons));
    };

    // 初始化所有节点的过滤按钮
    const initializeFilteredButtons = () => {
      props.treeData.forEach(data => {
        updateFilteredButtons(data);
      });
    };

    // 监听 treeData 变化并初始化过滤按钮
    watch(() => props.treeData, initializeFilteredButtons, { immediate: true, deep: true });

    // 返回所需的属性和方法
    return {
      ...toRefs(state),
      isAdmin,
      // filteredTreeData,
      tree,
      filterNode,
      labelMaxWidth,
      handleViewClick,
      handleNodeClick,
      handleDragStart,
      handleDragEnd,
      handleDrop,
      handleNavClick,
      More // 导出图标组件供模板使用
    };
  }
});
</script>

<style scoped>
/* 样式可以根据需要添加 */
.tree-wrapper {
  height: calc(100vh - 120px); /* 根据实际布局调整高度 */
  overflow-y: auto; /* 添加垂直滚动 */
  padding-right: 8px; /* 防止滚动条遮挡内容 */
}
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.vertical-more {
  margin-left: auto;
}

.vertical-more {
  transform: rotate(-90deg); /* 逆时针旋转90度 */
  display: inline-block; /* 确保旋转应用于整个图标 */
}

.node-content {
  display: flex;
  align-items: center; /* 确保图标和文本垂直居中 */
}


.node-label {
  /* overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis; */
  overflow: hidden;
  white-space: normal; /* 允许文本换行 */
  word-wrap: break-word; /* 允许长单词换行 */
  flex: 1; /* 使 label 占据剩余空间 */
}

.tree-trigger-nav .el-menu-item {
  padding: 5px !important;
  height: 35px;
}

/* 
.custom-tree-node .el-tooltip__trigger{
  position: absolute !important;
  top: 0;
  right: 0;
} */

/* 设置 more-button-container 的固定宽度 */
.more-button-container {
  position: relative; /* 相对定位，使子元素可以基于此容器绝对定位 */
  width: 10px; /* 根据需要调整宽度 */
  height: 100%; /* 确保与父级元素等高 */
  top:0;
  right: 0;
}

/* 设置 more-button 的样式 */
.more-button {
  position: absolute; /* 绝对定位，使按钮位于容器的右端 */
  display: flex;
  align-items: center;
  justify-content: center;
}


.node-right{
  position: absolute !important;
  top: 0;
  right: 0;
}

:deep(.el-tree-node) {
  white-space: normal;
  outline: 0;

  .el-tree-node__content {
    text-align: left;
    align-items: start;
    /* margin: 2px; */
    height: 100%;
  }
}

</style>